package com.tensin.mall.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tensin.common.contant.ProductConstant;
import com.tensin.mall.product.dao.AttrAttrgroupRelationDao;
import com.tensin.mall.product.dao.AttrGroupDao;
import com.tensin.mall.product.dao.CategoryDao;
import com.tensin.mall.product.entity.AttrAttrgroupRelationEntity;
import com.tensin.mall.product.entity.AttrGroupEntity;
import com.tensin.mall.product.entity.CategoryEntity;
import com.tensin.mall.product.service.CategoryService;
import com.tensin.mall.product.vo.AttrGroupRelationVo;
import com.tensin.mall.product.vo.AttrRespVo;
import com.tensin.mall.product.vo.AttrVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tensin.common.utils.PageUtils;
import com.tensin.common.utils.Query;

import com.tensin.mall.product.dao.AttrDao;
import com.tensin.mall.product.entity.AttrEntity;
import com.tensin.mall.product.service.AttrService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Autowired
    AttrAttrgroupRelationDao relationDao;

    @Autowired
    AttrGroupDao attrGroupDao;

    @Autowired
    CategoryDao categoryDao;

    @Autowired
    CategoryService categoryService;

    @Autowired
    AttrDao attrDao;


    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    //保存Attr属性表信息
    @Transactional
    @Override
    public void saveAttr(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();

        //属性复制
        BeanUtils.copyProperties(attrVo,attrEntity);

        //保存基本数据。保存到Attr表中
        this.save(attrEntity);

        //保存关联关系。仅在基本属性时设置，销售属性不用设置
        if (attrVo.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode() && attrVo.getAttrGroupId()!=null){
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attrVo.getAttrGroupId());
            relationEntity.setAttrId(attrEntity.getAttrId());
            relationDao.insert(relationEntity);
        }
    }

//    规格参数页面查询功能
    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long catelogId, String type) {

        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrEntity::getAttrType,
                "base".equalsIgnoreCase(type)?ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode():ProductConstant.AttrEnum.ATTR_TYPE_SALE.getCode());

        if (catelogId != 0){
            wrapper.eq(AttrEntity::getCatelogId,catelogId);
        }

        String key = (String) params.get("key");
        if (StringUtils.hasText(key)){

            wrapper.and(LambdaQueryWrapper -> LambdaQueryWrapper.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key));

//            wrapper.and(new Consumer<LambdaQueryWrapper<AttrEntity>>() {
//                @Override
//                public void accept(LambdaQueryWrapper<AttrEntity> LambdaQueryWrapper) {
//                    LambdaQueryWrapper.eq(AttrEntity::getCatelogId,key).or().like(AttrEntity::getAttrName,key);
//                }
//            });
        }


        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );

        PageUtils pageUtils = new PageUtils(page);
        List<AttrEntity> records = page.getRecords();

        List<AttrRespVo> respVos = records.stream().map((attrEntity -> {
            //先将属性表里的值都复制进来
            AttrRespVo attrRespVo = new AttrRespVo();
            BeanUtils.copyProperties(attrEntity, attrRespVo);


            //设置分类名字.仅在基本属性时设置，销售属性不用设置
            if ("base".equalsIgnoreCase(type)){
                LambdaQueryWrapper<AttrAttrgroupRelationEntity> relationWrapper = new LambdaQueryWrapper<>();
                relationWrapper.eq(AttrAttrgroupRelationEntity::getAttrId, attrEntity.getAttrId());
                AttrAttrgroupRelationEntity attrId = relationDao.selectOne(relationWrapper);

                if (attrId != null && attrId.getAttrGroupId()!=null) {
                    Long attrGroupId = attrId.getAttrGroupId();
                    AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrGroupId);
                    if(attrGroupEntity != null){
                        attrRespVo.setGroupName(attrGroupEntity.getAttrGroupName());
                    }
                }
            }


//           设置分组名字
            CategoryEntity categoryEntity = categoryDao.selectById(attrEntity.getCatelogId());
            if (categoryEntity != null) {
                attrRespVo.setCatelogName(categoryEntity.getName());
            }


            return attrRespVo;
        })).collect(Collectors.toList());

        pageUtils.setList(respVos);

        return pageUtils;
    }


    //平台规格-属性参数修改按钮回显
    @Override
    public AttrRespVo getAttrInfo(Long attrId) {
        AttrEntity byId = this.getById(attrId);
        AttrRespVo respVo = new AttrRespVo();
        BeanUtils.copyProperties(byId,respVo);


        //设置分类名字.仅在基本属性时设置，销售属性不用设置
        if (byId.getAttrType() == ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //设置分组id和分组名字
            LambdaQueryWrapper<AttrAttrgroupRelationEntity> relationWrapper = new LambdaQueryWrapper<>();
            relationWrapper.eq(AttrAttrgroupRelationEntity::getAttrId, attrId);
            AttrAttrgroupRelationEntity groupRelationId = relationDao.selectOne(relationWrapper);
            if (groupRelationId != null){
                respVo.setAttrGroupId(groupRelationId.getAttrGroupId());
                AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(groupRelationId.getAttrGroupId());
                if (attrGroupEntity != null){
                    respVo.setGroupName(attrGroupEntity.getAttrGroupName());
                }
            }
        }





        //设置获取全路径
        Long catelogId = byId.getCatelogId(); //当前三级分类id

        Long[] catelogPath = categoryService.findCatelogPath(catelogId);
        respVo.setCatelogPath(catelogPath);

        CategoryEntity categoryEntity = categoryDao.selectById(catelogId);
        if (categoryEntity != null){
            respVo.setCatelogName(categoryEntity.getName());
        }

        return respVo;
    }

    @Transactional
    @Override
    public void updateAttr(AttrVo attrVo) {
        AttrEntity attrEntity = new AttrEntity();
        BeanUtils.copyProperties(attrVo,attrEntity);
        //基本修改
        this.updateById(attrEntity);


        //设置分类名字.仅在基本属性时设置，销售属性不用设置
        if (attrEntity.getAttrType()== ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode()){
            //修改/新增分组关联
            AttrAttrgroupRelationEntity relationEntity = new AttrAttrgroupRelationEntity();
            relationEntity.setAttrGroupId(attrVo.getAttrGroupId());
            relationEntity.setAttrId(attrVo.getAttrId());

            LambdaQueryWrapper<AttrAttrgroupRelationEntity> attrGroupWrapper = new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().eq(AttrAttrgroupRelationEntity::getAttrId, attrVo.getAttrId());

            Integer integer = relationDao.selectCount(attrGroupWrapper);
            if (integer > 0){
                relationDao.update(relationEntity,attrGroupWrapper);
            } else {
                relationDao.insert(relationEntity);
            }


        }

    }

    //属性分组-关联按钮列表   根据分组id，找到组内关联的所有属性
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> wrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> in = wrapper.eq(AttrAttrgroupRelationEntity::getAttrGroupId, attrgroupId);
        //查出符合的关联表中的Entity
        List<AttrAttrgroupRelationEntity> attrIds = relationDao.selectList(in);


        //查询对应的attrEntity的id
        List<Long> attrIdList = attrIds.stream().map((attr) -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());


        if (attrIdList == null || attrIdList.size() == 0){
            return null;
        }
        //在Attr表中查出对应的AttrEntity
        List<AttrEntity> attrEntities = this.listByIds(attrIdList);

        return attrEntities;

    }

    //属性分组-关联-移除功能
    // 思路：直接删除关联表pms_attr_attrgroup_relation中数据即可。因为当时关联查询是通过了关联表查询。
    @Override
    public void deleteRelation(AttrGroupRelationVo[] vos) {
        List<Long> collect = Arrays.asList(vos).stream().map((ids) -> ids.getAttrId()).collect(Collectors.toList());

        LambdaQueryWrapper<AttrAttrgroupRelationEntity> groupWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<AttrAttrgroupRelationEntity> in = groupWrapper.in(AttrAttrgroupRelationEntity::getAttrId, collect);

        relationDao.delete(in);
    }

    /**
     *获取属性分组-关联-新建关联之查询出来目前没有关联的规格参数
     * @param params 前端收集来的页面信息
     * @param attrgroupId
     * @return
     */
    @Override
    public PageUtils getNoRelationAttr(Map<String, Object> params, Long attrgroupId) {
        //1.只能关联自己所属分类的属性
        AttrGroupEntity attrGroupEntity = attrGroupDao.selectById(attrgroupId);
        Long catelogId = attrGroupEntity.getCatelogId(); //225

        //2.只能关联别的分组没有引用的属性
        //2.1 当前分类下的其他分组
        LambdaQueryWrapper<AttrGroupEntity> attrGroupWrapper = new LambdaQueryWrapper<>();
        attrGroupWrapper.eq(AttrGroupEntity::getCatelogId,catelogId);
        List<AttrGroupEntity> group = attrGroupDao.selectList(attrGroupWrapper);
        List<Long> collect = group.stream().map(item -> item.getAttrGroupId()).collect(Collectors.toList());

        //找出分组关联的属性
        List<AttrAttrgroupRelationEntity> groupId = relationDao.selectList(new LambdaQueryWrapper<AttrAttrgroupRelationEntity>().in(AttrAttrgroupRelationEntity::getAttrGroupId, collect));
        List<Long> attrIds = groupId.stream().map(item -> item.getAttrId()).collect(Collectors.toList());

        //从当前分类属性中移除这些属性
        LambdaQueryWrapper<AttrEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(AttrEntity::getCatelogId,catelogId);

        if (attrIds != null && attrIds.size() > 0){
            wrapper.notIn(AttrEntity::getAttrId,attrIds);
        }

        wrapper.eq(AttrEntity::getAttrType,ProductConstant.AttrEnum.ATTR_TYPE_BASE.getCode());


        String key = (String) params.get("key");
        if (StringUtils.hasText(key)){
            wrapper.and((w)->{
                w.eq(AttrEntity::getAttrId,key).or().like(AttrEntity::getAttrName,key);
            });
        }


        //封装
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                wrapper
        );

        PageUtils pageUtils = new PageUtils(page);


        return pageUtils;
    }

    //过滤后都是可以被检索的的attrIds（即search的值为1）
    @Override
    public List<Long> selectSearchAttrIds(List<Long> baseAttrIds) {

        LambdaQueryWrapper<AttrEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.in(AttrEntity::getAttrId,baseAttrIds).and(r-> {
//            r.eq(AttrEntity::getSearchType, 1);
//        });
        if (queryWrapper != null){
            queryWrapper.in(AttrEntity::getAttrId,baseAttrIds);
            queryWrapper.eq(AttrEntity::getSearchType,1);
        }


        List<AttrEntity> list = this.list(queryWrapper);
        List<Long> searchAttrIds = list.stream().map(attr -> {
            return attr.getAttrId();
        }).collect(Collectors.toList());

        return searchAttrIds;
    }

}